#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/select.h>
#include "server.h"

int main()
{
    TcpServer server;
    int       listenfd, acceptfd, i;
    listenfd = server.TcpInit();
    // acceptfd = server.TcpAceept(listenfd);
    char buf[1024] = {0};
    //使用的表和备用的表(用于接收表的改变，然后修正rdfs)
    fd_set rdfs, temfs;
    int    maxfd = listenfd;
    FD_ZERO(&rdfs);
    //向表中添加文件描述符
    FD_SET(listenfd, &rdfs);
    //确保监听套接字在备用表上
    temfs = rdfs;
    while(1) {
        rdfs    = temfs;
        int ret = select(maxfd + 1, &rdfs, NULL, NULL, NULL);
        /**
         * @description:
         * 对表中的文件描述符进行轮询，看有没有数据可读或者写或者错误操作。
         * @param
         * {*}参数1:文件描述符中的最大值+1，参数2-4:表中的文件描述符是否可读或可写或错误操作
         * 参数5:超时检测
         * @return {*}-1:出错;0:超时;其它:准备好的文件描述符个数
         */
        if(-1 == ret) {
            perror("select:");
            exit(-1);
        }
        //由于没有设置超时检测，不会出现返回值为0的情况
        //遍历表
        for(i = listenfd; i < maxfd + 1; ++i) {
            //有文件描述符准备好了
            if(FD_ISSET(i, &rdfs)) {
                if(i == listenfd) {
                    acceptfd = server.TcpAceept(i);
                    //添加道备用表
                    printf("套接字文件描述符:%d\n", acceptfd);
                    FD_SET(acceptfd, &temfs);
                    //修正maxfd
                    maxfd = maxfd > acceptfd ? maxfd : acceptfd;
                } else {
                    memset(buf, 0, sizeof(buf));
                    int len = read(i, buf, sizeof(buf));
                    if(0 >= len) {
                        printf("客户端%d退出\n", i);
                        close(i);
                        FD_CLR(i, &temfs);
                        // close(i);
                    }
                    printf("read:%dbytes,buf:%s\n", len, buf);
                }
            }
        }
    }
    return 0;
}